package com.sy.filter;

import com.sy.bean.HttpOperation;
import com.sy.exception.NotFoundException;
import com.sy.utils.ApplicationContextUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.NestedServletException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class CommonExceptionFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException {
        HttpOperation httpOperation = ApplicationContextUtils.getBean(HttpOperation.class);
        try {
            filterChain.doFilter(req, res);
        } catch (Exception e) {
            e.printStackTrace();
            //这里的有的异常就是直接我们手动抛出的
            //而有些异常尽管我们手动抛出，但是被Spring包装了，
            //所以这里的Cause才是直接抛出的异常本身
            List<Throwable> exceptions = new ArrayList<>();
            exceptions.add(e);
            exceptions.add(e.getCause());
            Iterator<? extends Throwable> exIterator = exceptions.iterator();
            while (exIterator.hasNext()) {
                Throwable ex = exIterator.next();
                if (null == ex || ex.getClass() == NestedServletException.class) {
                    exIterator.remove();
                }
            }
            e = (Exception) exceptions.get(0);
            if (e instanceof ExpiredJwtException) {
                httpOperation.writeJson(401, "登录信息已过期");
            } else if (e instanceof BadCredentialsException) {
                httpOperation.writeJson(401, e.getMessage());
            } else if (e instanceof MalformedJwtException) {
                httpOperation.writeJson(400, "Token格式不合法");
            } else if (e instanceof IllegalArgumentException) {
                httpOperation.writeJson(400, e.getMessage());
            } else if (e instanceof AccessDeniedException) {
                httpOperation.writeJson(403, e.getMessage());
            } else if (e instanceof NotFoundException) {
                httpOperation.writeJson(404, e.getMessage());
            } else {
                httpOperation.writeJson(500, "服务器异常");
            }
        }
    }

}
